/*
 * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0.
 *
 * @Date: 2021-04-07 09:53:07
 * @LastEditTime: 2021-07-02 16:56:15
 * @Description:  This files is for uart functions
 *
 * @Modify History:
 *  Ver   Who        Date         Changes
 * ----- ------     --------    --------------------------------------
 */

#ifndef BSP_DRIVERS_USART_PL011_UART_H
#define BSP_DRIVERS_USART_PL011_UART_H

#include "ft_types.h"
#include "ft_assert.h"

#include "pl011_uart_hw.h"

#define ERR_INPUT_BAUD_NO_SUPPORT FT_CODE_ERR(ErrModBsp, ErrBspUart, 0x1u)

#define FUART_BAUDRATE 115200U

/* Config options */
#define FUART_OPTION_UARTEN 0x1U
#define FUART_OPTION_RXEN 0x2U
#define FUART_OPTION_TXEN 0x4U
#define FUART_OPTION_FIFOEN 0x8U

/* Data format values  */
#define FUART_FORMAT_WORDLENGTH_8BIT 0x3
#define FUART_FORMAT_WORDLENGTH_7BIT 0x2
#define FUART_FORMAT_WORDLENGTH_6BIT 0x1
#define FUART_FORMAT_WORDLENGTH_5BIT 0x0

#define FUART_FORMAT_NO_PARITY 0U
#define FUART_FORMAT_MARK_PARITY 1U
#define FUART_FORMAT_SPACE_PARITY 2U
#define FUART_FORMAT_ODD_PARTY 3U
#define FUART_FORMAT_EVEN_PARITY 4U

#define FUART_FORMAT_2_STOP_BIT 0U
#define FUART_FORMAT_1_STOP_BIT 1U

/* Callback events  */

#define FUART_EVENT_RECV_DATA 1U       /**< Data receiving done */
#define FUART_EVENT_RECV_TOUT 2U       /**< A receive timeout occurred */
#define FUART_EVENT_SENT_DATA 3U       /**< Data transmission done */
#define FUART_EVENT_RECV_ERROR 4U      /**< A receive error detected */
#define FUART_EVENT_MODEM 5U           /**< Modem status changed */
#define FUART_EVENT_PARE_FRAME_BRKE 6U /**< A receive parity, frame, break \
                                        *   error detected */
#define FUART_EVENT_RECV_ORERR 7U      /**< A receive overrun error detected */

/**************************** Type Definitions ******************************/
typedef struct
{
    u32 instance_id; /* Id of device*/
    u32 base_address;
    u32 ref_clock_hz;
    u32 irq_num;
} Pl011Config;

typedef struct
{
    u8 *byte_p;
    u32 requested_bytes;
    u32 remaining_bytes;
} Pl011Buffer;

typedef void (*Pl011EventHandler)(void *args, u32 event, u32 event_data);

typedef struct
{
    Pl011Config config; /* Configuration data structure  */
    u32 is_ready;       /* Device is ininitialized and ready*/
    u32 baudrate;

    Pl011Buffer send_buffer;
    Pl011Buffer receive_buffer;

    Pl011EventHandler handler;
    void *args;
    uint8_t rxbs_error; /* 接收过程中出现错误 ，0 无错误，1 存在错误*/

} Pl011;

void Pl011PutChar(Pl011 *uart_p, s8 Data);
u32 Pl011Send(Pl011 *uart_p, u8 *Buffer, u32 Length);
u32 Pl011Receive(Pl011 *uart_p, u8 *byte_p, u32 Length);
u8 Pl011BlockReceive(Pl011 *uart_p);
s32 Pl011CfgInitialize(Pl011 *uart_p, Pl011Config *Config);
Pl011Config *Pl011LookupConfig(u32 instance_id);
void Pl011SetOptions(Pl011 *uart_p, u32 options);
void Pl011SetSpecificOptions(Pl011 *uart_p, u32 options);
void Pl011ClearSpecificOptions(Pl011 *uart_p, u32 options);
void Pl011InterruptHandler(Pl011 *uart_p);
void Pl011SetHandler(Pl011 *uart_p, Pl011EventHandler fun_p, void *args);
void Pl011SetInterruptMask(Pl011 *uart_p, u32 Mask);
u32 Pl011SetBaudRate(Pl011 *uart_p, u32 baudrate);
void Pl011IrqClearReciveTimeOut(Pl011 *uart_p);
void Pl011IrqEnableReciveTimeOut(Pl011 *uart_p);
u32 Pl011GetInterruptMask(Pl011 *uart_p);
void Pl011BlockSend(Pl011 *uart_p, u8 *byte_p, u32 Length);

#endif // !
